package uk.org.scuts.bantstadium2.attacks;

import java.util.Random;

import uk.org.scuts.bantstadium2.Character;

public class Attack {
	// Constructors
	public Attack() {
		_name = "Default Attack";
		_aggressionFactor = 100;
		_accuracy = 70;
		_power = 1.0;
		_criticalRequirement = 8.0;
		_normalRequirement = 1.5;
		_hitRequirement = 0.95;
	}
	
	// Methods
	public String Execute(Character user, Character target) {
		String log = (user.Name() + " targets " + target.Name() + " with a " + _name);
		switch (Hits(user, target)) {
		case MISS: 
			log += (" but misses. ");
		    break;
		case GLANCING:
			log += (" and scores a glancing blow. ");
			log += target.Hit(user.Attack() * 0.5 * _power);
		    break;
		case NORMAL: 
			log += (" and connects. ");
        	log += target.Hit(user.Attack() * _power);
        	break;
		case CRITICAL: 
			log += (" and scores a critical hit. ");
			log += target.Hit(user.Attack() * 2 * _power);
			break;
		}
		return log;
	}
	
	public void Setup(Character user, Character target) {
		// Do nothing
	}
	
	public void Restore(Character user, Character target) {
		// Do nothing
	}
	
	hitType Hits(Character user, Character target) {
		if (user.Accuracy() < 0) {
			return hitType.MISS;
		} else if (target.Evasion() < 0) {
			return hitType.CRITICAL;
		} else {
			double rand = new Random().nextInt(100);
			double hitAccuracy = _accuracy * (Math.sqrt(user.Accuracy())/Math.sqrt(target.Evasion()));
			double hitRatio = hitAccuracy / rand;
			if (hitRatio > _criticalRequirement) {
				return hitType.CRITICAL;
			} else if (hitRatio > _normalRequirement) {
				return hitType.NORMAL;
			} else if (hitRatio > _hitRequirement) {
				return hitType.GLANCING;
			} else {
				return hitType.MISS;
			}
		}
	}
	
	enum hitType { MISS, GLANCING, NORMAL, CRITICAL };
	
	public String Name() { return _name; }
	
	// Members
	String _name;
	int _aggressionFactor;
	int _accuracy;
	double _power;
	double _criticalRequirement;
	double _normalRequirement;
	double _hitRequirement;
}
